#include "MediaFormatFactoryThread.h"
#include <QThread>
#include <QDebug>
extern "C"
{
#include <libavformat/avformat.h>
}

MediaFormatFactoryThread::MediaFormatFactoryThread()
{

}

void MediaFormatFactoryThread::run()
{
	qDebug() << "转换开始";
	//1.打开输入文件
	AVFormatContext* ic = NULL;
	avformat_open_input(&ic, inFile.toStdString().c_str(), 0, 0);
	if (!ic)
	{
		qDebug() << "avformat_open_input failed!";
		return;
	}

	///创建输出格式上下文
	AVFormatContext* oc = NULL;
	avformat_alloc_output_context2(&oc, NULL, NULL, outFile.toStdString().c_str());
	if (!oc)
	{
		qDebug() << "avformat_alloc_output_context2 " << outFile.toStdString().c_str() << " failed!";
		return;
	}

	///创建音视频流
	AVStream* videoStream = avformat_new_stream(oc, NULL);
	AVStream* audioStream = avformat_new_stream(oc, NULL);

	///将输入格式上下文参数，copy到输出流参数中
	avcodec_parameters_copy(videoStream->codecpar, ic->streams[0]->codecpar);
	avcodec_parameters_copy(audioStream->codecpar, ic->streams[1]->codecpar);

	//清理tag标签
	videoStream->codecpar->codec_tag = 0;
	audioStream->codecpar->codec_tag = 0;


	///打开写入io
	int ret = avio_open(&oc->pb, outFile.toStdString().c_str(), AVIO_FLAG_WRITE);
	if (ret < 0)
	{
		qDebug() << "avio open failed!";
		return;
	}
	//写入文件头
	ret = avformat_write_header(oc, NULL);
	if (ret < 0)
	{
		qDebug() << "avformat_write_header failed!";
		return;
	}

	AVPacket pkt;
	for (;;)
	{
		int re = av_read_frame(ic, &pkt);//从文件中读取tacket
		if (re < 0)
			break;
		pkt.pts = av_rescale_q_rnd(pkt.pts,
			ic->streams[pkt.stream_index]->time_base,
			oc->streams[pkt.stream_index]->time_base,
			(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)
		);
		pkt.dts = av_rescale_q_rnd(pkt.dts,
			ic->streams[pkt.stream_index]->time_base,
			oc->streams[pkt.stream_index]->time_base,
			(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)
		);
		pkt.pos = -1;
		pkt.duration = av_rescale_q_rnd(pkt.duration,
			ic->streams[pkt.stream_index]->time_base,
			oc->streams[pkt.stream_index]->time_base,
			(AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)
		);

		av_write_frame(oc, &pkt);//将packet写入文件
		av_packet_unref(&pkt);
		qDebug() << "+";
	}

	av_write_trailer(oc);//写入尾部
	avio_close(oc->pb);
	qDebug() << "结束";

}
void MediaFormatFactoryThread::Start()
{
	qDebug() << "启动线程";
	//开启线程
	this->start();
}

MediaFormatFactoryThread::~MediaFormatFactoryThread()
{
}
